<script>
import draggable from 'vuedraggable'
import render from '@/views/workflow/components/generator/render'
import DeptSelect from '@/components/DeptSelect'
import DeptPositionS from '@/components/DeptPositionS'
import DeptUserS from '@/components/DeptUserS'
import DeptPositionUser from '@/components/DeptPositionUser'
import UserLink from '@/components/UserLink'
import SupplierLink from '@/components/SupplierLink'
import UserFile from '@/components/UserFile'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'

const components = {
  itemBtns(h, element, index, parent) { // 单个组件的工具栏
    const { copyItem, deleteItem } = this.$listeners
    return [
      <span class="drawing-item-copy" title="复制" onClick={event => {
        copyItem(element, parent); event.stopPropagation()
      }}>
        <i class="el-icon-copy-document" />
      </span>,
      <span class="drawing-item-delete" title="删除" onClick={event => {
        deleteItem(index, parent); event.stopPropagation()
      }}>
        <i class="el-icon-delete" />
      </span>
    ]
  },
  tableColumn(h, element, index, parent) { // 表格的列
    if (!Array.isArray(element.columns)) return null
    return element.columns.map((column, i) => {
      if (column.visible === false) return null
      element.currentColumn = column
      // const columnTag = components.tableColumnTemplate.call(this, h, column)
      const columnTag = components.tableColumnTemplate.call(this, h, column)
      return (
        <el-table-column
          type={column.type || undefined}
          column-key={column.columnKey}
          label={column.label}
          prop={column.prop}
          width={column.width || undefined}
          min-width={column.minWidth || undefined}
          fixed={column.fixed || undefined}
          sortable={column.sortable}
          resizable={column.resizable}
          align={column.align || undefined}
          header-align={column.headerAlign || undefined}
          {
            ...columnTag
          }
        >
        </el-table-column>
      )
    })

    // 利用formatter的方式
    // formatter={
    //   (row, col, cell) => {
    //     const columnTag = components.tableColumnTemplate.call(this, h, column, row, col, cell)
    //     return columnTag
    //   }
    // }
  },
  // 利用formatter的方式
  // tableColumnTemplate(h, column, row, col, cell) {
  //   if (column.editDef) {
  //     if (column.type === '') {
  //       return (
  //         <div>
  //           <render conf={column.editDef} row={row} col={col} cell={cell} />
  //         </div>
  //       )
  //     }
  //   }
  //   return null
  // }
  tableColumnTemplate(h, column) {
    let res = {}
    if (['', 'selection', 'index', 'expand'].indexOf(column.type) <= -1) {
      res = {
        scopedSlots: {
          default: props => {
            if (column.type === 'el-input') {
              return <el-input
                  type="text"
                  placeholder={`请输入${column.label}`}
                  v-model={props.row[props.column.property]}
                  clearable />
            } else if (column.type === 'el-select') {
              return <el-select
                  placeholder={`请选择${column.label}`}
                  v-model={props.row[props.column.property]}
                  clearable >
                    <el-option key={1} label="男" value={1}></el-option>
                    <el-option key={0} label="女" value={0}></el-option>
                  </el-select>
                  
            } else if (column.type === 'el-date-picker') {
              return <el-date-picker
                    v-model={props.row[props.column.property]}
                    type="date"
                    placeholder={`请选择${column.label}`}>
                  </el-date-picker>
                  
            }
          }
        }
      }
    }
    return res
  }
}

const layouts = {
  // sysComponents: {
  //   colLinkItem(h, element, index, parent) {
  //     const { activeItem } = this.$listeners
  //     let className = this.activeId === element.formId ? 'drawing-item active-from-item' : 'drawing-item'
  //     if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
  //     let labelWidth = element.labelWidth ? `${element.labelWidth}px` : null
  //     if (element.showLabel === false) labelWidth = '0'
  //     return (
  //       <el-col span={element.span} class={className}
  //         nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
  //         <el-form-item label-width={labelWidth}
  //           label={element.showLabel ? element.label : ''}>
  //           <el-link type="primary">{element.defaultValue}</el-link>
  //         </el-form-item>
  //         {components.itemBtns.apply(this, arguments)}
  //       </el-col>
  //     )
  //   },
  //   colLinkItem(h, element, index, parent) {
  //     const { activeItem } = this.$listeners
  //     let className = this.activeId === element.formId ? 'drawing-item active-from-item' : 'drawing-item'
  //     if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
  //     let labelWidth = element.labelWidth ? `${element.labelWidth}px` : null
  //     if (element.showLabel === false) labelWidth = '0'
  //     return (
  //       <el-col span={element.span} class={className}
  //         nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
  //         <el-form-item label-width={labelWidth}
  //           label={element.showLabel ? element.label : ''}>
  //           <el-link type="primary">{element.defaultValue}</el-link>
  //         </el-form-item>
  //         {components.itemBtns.apply(this, arguments)}
  //       </el-col>
  //     )
  //   },
  //   colLinkItem(h, element, index, parent) {
  //     const { activeItem } = this.$listeners
  //     let className = this.activeId === element.formId ? 'drawing-item active-from-item' : 'drawing-item'
  //     if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
  //     let labelWidth = element.labelWidth ? `${element.labelWidth}px` : null
  //     if (element.showLabel === false) labelWidth = '0'
  //     return (
  //       <el-col span={element.span} class={className}
  //         nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
  //         <el-form-item label-width={labelWidth}
  //           label={element.showLabel ? element.label : ''}>
  //           <el-link type="primary">{element.defaultValue}</el-link>
  //         </el-form-item>
  //         {components.itemBtns.apply(this, arguments)}
  //       </el-col>
  //     )
  //   },
  // },
  colFormTag(h, element){
    if (element.sysType) {
      if (element.sysType === 'link') {
        if (element.tagType === 'user-info') {
          return (
            <user-link id={element.defaultValue}/>
          )
        } else if (element.tagType === 'supplier-info') {
          return (
            <supplier-link id={element.defaultValue}/>
          )
        }
      } else if (element.sysType === 'select') {
        if (element.tagType === 'dept-tree-select') {
          return (
            <DeptSelect 
              selectValue={element.defaultValue}
              placeholder={element.placeholder}
              multiple={element.multiple} 
              disabled={element.disabled} 
              clearable={element.clearable} 
            />
          )
        } else if (element.tagType === 'dept-pos-tree-select') {
          return (
            <DeptPositionS 
              selectValue={element.defaultValue}
              placeholder={element.placeholder}
              multiple={element.multiple} 
              disabled={element.disabled} 
              clearable={element.clearable} 
            />
          )
        } else if (element.tagType === 'dept-user-tree-select') {
          return (
            <DeptUserS 
              selectValue={element.defaultValue}
              placeholder={element.placeholder}
              multiple={element.multiple} 
              disabled={element.disabled} 
              clearable={element.clearable} 
            />
          )
        } else if (element.tagType === 'dept-pos-user-dialog') {
          return (
            <DeptPositionUser 
              multiple={element.multiple} 
              disabled={element.disabled}
            />
          )
        }
      } else {
        if (element.tag === 'user-file') {
          return (
            <UserFile/>
          )
        }
      }
    }
    else if (element.tag === 'p') { // 表单文本组件
      return (
        <p>{element.defaultValue}</p>
      )
    } else {
      return (
        <render key={element.renderKey} 
        conf={element} 
        onInput={ event => {
          this.$set(element, 'defaultValue', event)
        }} />
      )
    }
  },
  colFormItem(h, element, index, parent) {
    const { activeItem } = this.$listeners
    let className = this.activeId === element.formId ? 'drawing-item active-from-item' : 'drawing-item'
    if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
    let labelWidth = element.labelWidth ? `${element.labelWidth}px` : null
    if (element.showLabel === false) labelWidth = '0'
    const tag = layouts.colFormTag.call(this, h, element)
    // 计数器后面可选择是否显示单位
    const unit = element.tag === 'el-input-number' && element.unit ? `\u00a0\u00a0${element.unit}` : undefined
    return (
      <el-col span={element.span} class={className}
        nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
        <el-form-item label-width={labelWidth}
          label={element.showLabel ? element.label : ''} required={element.required}>
          {tag}{unit}
        </el-form-item>
        {components.itemBtns.apply(this, arguments)}
      </el-col>
    )
  },
  rowFormItem(h, element, index, parent) {
    const { activeItem } = this.$listeners
    const className = this.activeId === element.formId ? 'drawing-row-item active-from-item' : 'drawing-row-item'
    let child = renderChildren.apply(this, arguments)
    if (element.type === 'flex') {
      child = <el-row type={element.type} justify={element.justify} align={element.align}>
        {child}
      </el-row>
    }
    return (
      <el-col span={element.span}>
        <el-row gutter={element.gutter} class={className}
          nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
          <span class="component-name">{element.componentName}</span>
          <draggable list={element.children} animation={340} group="componentsGroup" class="drag-wrapper">
            {child}
          </draggable>
          {components.itemBtns.apply(this, arguments)}
        </el-row>
      </el-col>
    )
  },
  textItem(h, element, index, parent) {
    const { activeItem } = this.$listeners
    const className = this.activeId === element.formId ? 'drawing-row-item active-from-item' : 'drawing-row-item'
    const style = `width:100%;font-size:${element.fontSize};color:${element.fontColor};text-align:${element.align};`
    return (
      <el-col span={element.span}>
        <el-row class={className}
          nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
          <span class="component-name">{element.componentName}</span>
          <p style={style} >{element.content}</p>
          {components.itemBtns.apply(this, arguments)}
        </el-row>
      </el-col>
    )
  },
  tabsItem(h, element, index, parent) {
    const { activeItem } = this.$listeners
    const className = this.activeId === element.formId ? 'drawing-card-item active-from-item' : 'drawing-card-item'
    return (
      <el-col span={element.span}>
        <el-tabs v-model={element.defaultValue} type={element.type} tab-position={element.tabPosition} class={className}
          nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
          <span class="component-name">{element.componentName}</span>
          {
            element.tabs.map(item => {
              const child = renderTabChildren.call(this, item, ...arguments)
              return (
                <el-tab-pane label={item.label} name={item.name}>
                  <draggable list={item.children} animation={340} group="componentsGroup" class="drag-wrapper">
                    {child}
                  </draggable>
                </el-tab-pane>
              )
            })
          }
          {components.itemBtns.apply(this, arguments)}
        </el-tabs>
      </el-col>
    )
  },
  cardItem(h, element, index, parent) {
    const { activeItem } = this.$listeners
    const className = this.activeId === element.formId ? 'drawing-card-item active-from-item' : 'drawing-card-item'
    const child = renderChildren.apply(this, arguments)
    return (
      <el-col span={element.span}>
        <el-card header={element.header} shadow={element.shadow} body-style={element.bodyStyle} class={className}
          nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
          <span class="component-name">{element.componentName}</span>
          <draggable list={element.children} animation={340} group="componentsGroup" class="drag-wrapper">
            {child}
          </draggable>
          {components.itemBtns.apply(this, arguments)}
        </el-card>
      </el-col>
    )
  },
  tableItem(h, element, index, parent) {
    const { activeItem } = this.$listeners;
    const className =
      this.activeId === element.formId
        ? "drawing-row-item active-from-item"
        : "drawing-row-item"
    const columns = components.tableColumn.apply(this, arguments)
    return (
      <el-col span={element.span}>
        <el-row
          class={className}
          nativeOnClick={event => {
            activeItem(element)
            event.stopPropagation()
          }}
        >
          <span class="component-name">{element.componentName}</span>
          {components.itemBtns.apply(this, arguments)}
          <el-table
            style="width: 100%"
            height={element.height || undefined}
            max-height={element.maxHeight || undefined}
            stripe={element.stripe || undefined}
            border={element.border || undefined}
            size={element.size || undefined}
            fit={element.fit || undefined}
            show-header={element.showHeader || undefined}
            highlight-current-row={element.highlightCurrentRow || undefined}
            current-row-key={element.currentRowKey || undefined}
            data={null}
          >
            { columns }
          </el-table>
        </el-row>
      </el-col>
    )
  }
}

// 渲染布局型组件的子容器
function renderChildren(h, element, index, parent) {
  if (!Array.isArray(element.children)) return null
  return element.children.map((el, i) => {
    const layout = layouts[el.layout]
    if (layout) {
      return layout.call(this, h, el, i, element.children)
    }
    return layoutIsNotFound.call(this)
  })
}

// 渲染tabs页的标签子容器
function renderTabChildren(tab, h, element, index, parent) {
  if (!Array.isArray(tab.children)) return null
  return tab.children.map((el, i) => {
    const layout = layouts[el.layout]
    if (layout) {
      return layout.call(this, h, el, i, tab.children)
    }
    return layoutIsNotFound.call(this)
  })
}

function layoutIsNotFound() {
  throw new Error(`没有与${this.element.layout}匹配的layout`)
}

export default {
  components: {
    render,
    draggable,
    DeptSelect,
    DeptPositionS,
    DeptUserS,
    DeptPositionUser,
    UserLink,
    SupplierLink,
    UserFile
  },
  props: [
    'element',
    'index',
    'drawingList',
    'activeId',
    'formConf'
  ],
  data() {
    return {
    }
  },
  render(h) {
    const layout = layouts[this.element.layout]
    if (layout) {
      return layout.call(this, h, this.element, this.index, this.drawingList)
    }
    return layoutIsNotFound.call(this)
  }
}
</script>
